﻿/*
 * This Code is licensed under LGPL 3.0 (at least for now... 
 * might try another license later but as it is now its under LGPL
 * Share and enjoy!
 * http://www.gnu.org/licenses/lgpl.html
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Omnicatz.Handlers
{
    public class AjaxMethod : Attribute { }
    public abstract class GenericHandler<T> : IHttpHandler, System.Web.SessionState.IRequiresSessionState
    {
        public static string Serialize(object o)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(builder))
            {
                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(o.GetType());
                serializer.Serialize(writer, o);
            
            }
            return builder.ToString();
        }
        public static T Deserialize(string xml)
        {
            T result;
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(xml))) {
               System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
               result =  (T) serializer.Deserialize(stream);
            }
            return result;
        }
        public string GetFilePath(){
            string result ="";
            int i = HttpContext.Current.Request.Url.AbsoluteUri.IndexOf("?");

            if (i == -1)
                result = HttpContext.Current.Request.Url.AbsoluteUri;
            else
                result = HttpContext.Current.Request.Url.AbsoluteUri.Substring(0, i);
            return result;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        public void DoAction(String FunctionName)
        {
            System.Reflection.MethodInfo method = this.GetType().GetMethod(FunctionName);


          //  int i = 0; for (int y=0; y < method.GetCustomAttributes(true).Length; y++) {i++;}
            bool IsAjaxMethod = method.GetCustomAttributes(true).Count(n => n.GetType() == typeof(Handlers.AjaxMethod)) > 0;


            if (IsAjaxMethod) //i > 0)
            {
                System.Reflection.ParameterInfo[] infos = method.GetParameters();
                List<Object> parameters = new List<Object>();
                foreach (System.Reflection.ParameterInfo info in infos)
                {
                    Object o = HttpContext.Current.Request.Params[info.Name];
                    parameters.Add(o);
                }
                method.Invoke(this, parameters.ToArray());
            }
        }
        public virtual void GetScriptClient()
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            builder.Append(@"function ");
            builder.Append(this.GetType().Name);
            builder.Append(@"(){}
");
            foreach (System.Reflection.MethodInfo method in this.GetType().GetMethods())
            {
                bool IsAjaxMethod = method.GetCustomAttributes(true).Count(n => n.GetType() == typeof(Handlers.AjaxMethod)) > 0;

                if (IsAjaxMethod)
                {
                    builder.Append(this.GetType().Name);
                    builder.Append(".");
                    builder.Append(method.Name);
                    builder.Append(" = function(");
                    string mathodName = method.Name;
                    Dictionary<String, Type> dir = new Dictionary<string, Type>();
                    Dictionary<String, Type> dir2 = new Dictionary<string, Type>();
                    foreach (System.Reflection.ParameterInfo parameter in method.GetParameters())
                    {
                        dir.Add(parameter.Name, parameter.ParameterType);
                        dir2.Add(parameter.Name + "_", parameter.ParameterType);
                    }
                    builder.Append(string.Join(",", dir2.Keys.ToArray()));
                    builder.Append(@",callback)
{
$.post(""");
                    builder.Append(this.GetFilePath());
                    builder.Append(@""",{
action:""");
                    builder.Append(method.Name);
                    builder.Append(@"""");
                    foreach (KeyValuePair<String, Type> item in dir)
                    {
                        builder.Append(",");
                        builder.Append(item.Key);
                        builder.Append(":");
                        builder.Append(item.Key);
                        builder.Append("_");
                    }
                    builder.Append(@"},callback);
};");
                }
            }
            HttpContext.Current.Response.ContentType = "text/javascript";
            string script = builder.ToString();
            HttpContext.Current.Response.Write(script);
        }




        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.Params["action"] != null)
            {
                if (context.Request.Params["action"] == "ScriptClient__")
                {
                    this.GetScriptClient();
                }
                else
                {
                    this.DoAction(context.Request.Params["action"]);
                }
            }

        }
     
    }

   

}

